home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 17
/
CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso
/
CUCD
/
Programming
/
DiceSource
/
src
/
dutil
/
save
/
fdtolib.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-30
|
21KB
|
1,013 lines
/*
* FDTOLIB.C
*
* (c)Copyright 1992 Obvious Implementations Corp, All Rights Reserved
*
* FDTOLIB fdfile[s] [-h hdrfile] -o libname [-mr] [-mD] [-pprefix] -I incldir
* -prof -mc -mC -auto libname -AUTO libname
*
* Generates a normal model or registerized modem library interface given
* any set of FD files.
*
* -ms, -r, and -pr are ignored
*/
#ifndef unix
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#endif
/*#include <clib/alib_protos.h>*/
#ifndef LATTICE
#ifndef unix
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/alib_protos.h>
#endif
#else
#include <proto/exec.h>
#include <proto/dos.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <lib/profile.h>
#include <lib/version.h>
#ifdef unix
#include <../suplib/all.h>
#endif
#ifndef L_tmpnam
#define L_tmpnam 64
#endif
#define RF_SCRATCH 0x0303
#define RB_BP (8+6)
#define RF_BP (1 << RB_BP)
#ifdef _DCC
IDENT("fdtolib", ".5");
DCOPYRIGHT;
#endif
typedef unsigned short uword;
typedef struct List List;
typedef struct Node Node;
typedef struct LVONode {
Node lv_Node;
short lv_Offset;
} LVONode;
typedef struct RSNode {
Node rn_Node;
short rn_Args; /* -1 specifies stack */
short rn_Flag; /* equiv/fd found */
short rn_Regs[32]; /* transfer registers */
} RSNode;
void help(int);
void ScanFD(FILE *, FILE *);
void ScanRSTmp(FILE *);
void GenerateFunction(FILE *, char *, char *, int);
int AssembleFile(char *, char *);
void JoinOutput(FILE *, char *);
char *RegMaskToStr(uword, short *);
uword RegsToMask(short *, short);
char *RegToStr(short);
void RegsCall(FILE *, char *, long, RSNode *, short *);
void StackCall(FILE *, char *, long, short *, short);
short PushMask(FILE *, uword);
short PopMask(FILE *, uword);
void AddLVOList(char *, int);
void GenerateLVOList(FILE *);
void GenerateAutoOpen(FILE *, char *);
void DicePrefix(char *, char *, char *);
List FDList; /* list of FD files */
List RSList; /* register spec list */
List LVOList;
char DccOptsBuf[1024];
char *OutFile;
char *HdrFile;
char *FuncPrefix = "_";
char Buf[256];
char FuncName[256];
char Prefix[64];
short RegOpt;
short Verbose;
short SmallData = 1;
short SmallCode = 1;
short ProfOpt;
short AutoOpt;
char *DataModel = "(A4)";
char *CodeModel = "(PC)";
char *SharedLibName;
main(ac, av)
int ac;
char **av;
{
int i;
NewList(&FDList);
NewList(&RSList);
NewList(&LVOList);
DicePrefix(Prefix, av[0], "");
#ifndef LATTICE
#ifndef unix
expand_args(ac, av, &ac, &av);
#endif
#else
setbuf(stdout, NULL);
#endif
for (i = 1; i < ac; ++i) {
char *ptr = av[i];
if (*ptr != '-') {
Node *node = malloc(sizeof(Node));
node->ln_Name = ptr;
AddTail(&FDList, node);
continue;
}
ptr += 2;
switch(ptr[-1]) {
case 'a':
AutoOpt = 1;
SharedLibName = av[++i];
break;
case 'A':
AutoOpt = 2;
SharedLibName = av[++i];
break;
case 'p':
if (strcmp(ptr, "rof") == 0)
ProfOpt = 1;
else if (strcmp(ptr, "r") == 0) /* ignore -pr */
;
else
FuncPrefix = (*ptr) ? ptr : av[++i];
break;
case 'o':
OutFile = (*ptr) ? ptr : av[++i];
break;
case 'h':
HdrFile = (*ptr) ? ptr : av[++i];
break;
case 'm':
if (*ptr == 'r' || *ptr == 'R')
RegOpt = 1;
else if (*ptr == 'd') {
SmallData = 1;
DataModel = "(A4)";
} else if (*ptr == 'D') {
SmallData = 0;
DataModel = "";
} else if (*ptr == 'c') {
SmallCode = 1;
CodeModel = "(pc)";
} else if (*ptr == 'C') {
SmallCode = 0;
CodeModel = "";
} else if (*ptr == 's') {
/* ignore */
}
break;
case 'r':
/* ignore -r */
break;
case 'v':
++Verbose;
break;
case 'I':
sprintf(DccOptsBuf + strlen(DccOptsBuf), " -I%s", (*ptr) ? ptr : av[++i]);
break;
default:
help(1);
}
}
if (OutFile == NULL || (RegOpt && HdrFile == NULL))
help(ac != 1);
if (RegOpt == 0 && HdrFile)
puts("Warning: header file ignored (used only with -mr)");
/*
* step 2, ask DCC to generate a register specification file
*/
if (RegOpt) {
FILE *fi;
char rs_tmp[L_tmpnam];
sprintf(Buf, "%sdcc -mRRX %s -a -o %s%s",
Prefix,
HdrFile,
tmpnam(rs_tmp),
DccOptsBuf
);
puts(Buf);
#ifdef unix
system(Buf);
#else
Execute(Buf, NULL, NULL);
#endif
if ((fi = fopen(rs_tmp, "r")) == NULL) {
puts("Unable to generate register specification file");
help(20);
}
ScanRSTmp(fi);
fclose(fi);
remove(rs_tmp);
}
/*
* step 3
*/
{
FILE *fi;
FILE *fo = fopen(OutFile, "w");
Node *node;
if (fo == NULL) {
printf("Error, Unable to create %s\n", OutFile);
exit(20);
}
while (node = RemHead(&FDList)) {
printf("generate %s", node->ln_Name);
fi = fopen(node->ln_Name, "r");
if (fi) {
puts("");
ScanFD(fi, fo);
fclose(fi);
} else {
puts(" (open failed)");
}
}
}
{
#ifdef NOTDEF
RSNode *rs;
for (rs = RSList.lh_Head; rs->rn_Node.ln_Succ; rs = (RSNode *)rs->rn_Node.ln_Succ) {
if (rs->rn_Flag == 0)
printf("Warning, no FD entry found for: %s\n", rs->rn_Node.ln_Name);
}
#endif
}
return(0);
}
void
help(code)
{
#ifdef _DCC
puts(Ident);
#endif
puts("FDTOLIB files/wildcard [-h hdrfile] -o libname [-mr] [-mD]");
puts(" -mr : generate registered library from header & fd file");
puts(" -mD : large data model (else small data model)");
exit(code);
}
void
ScanFD(fi, fo)
FILE *fi;
FILE *fo;
{
char *base = NULL;
long bias = -1;
short end = 0;
short public = 1;
char *key;
while (fgets(Buf, sizeof(Buf), fi)) {
if (Buf[0] == '\n' || Buf[0] == '*')
continue;
if (strncmp(Buf, "##", 2) != 0) {
if (bias < 0 || base == NULL) {
printf("Error, No ##base/##bias before function: %s\n", Buf);
continue;
}
if (public && AutoOpt != 2)
GenerateFunction(fo, Buf, base, bias);
bias += 6;
continue;
}
if ((key = strtok(Buf + 2, " \t\n")) == NULL) {
printf("\tError, Illegal null directive\n");
continue;
}
if (stricmp(key, "base") == 0) {
if (key = strtok(NULL, " \t\n")) {
if (base)
free(base);
base = strdup(key);
} else {
printf("\tError, Illegal ##base directive\n");
}
continue;
}
if (stricmp(key, "bias") == 0) {
if (key = strtok(NULL, " \t\n")) {
char *dummy;
bias = strtol(key, &dummy, 0);
if (bias <= 0)
printf("\tError, Illegal ##bias: %d\n", bias);
} else {
printf("\tError, Illegal ##bias directive\n");
}
continue;
}
if (stricmp(key, "public") == 0) {
public = 1;
continue;
}
if (stricmp(key, "private") == 0) {
public = 0;
continue;
}
if (stricmp(key, "end") == 0) {
end = 1;
break;
}
printf("\tError, Unrecognized directive: %s\n", key);
}
if (bias < 0)
puts("\tUnexpected EOF, no ##bias");
if (base == NULL)
puts("\tUnexpected EOF, no ##base");
if (end == 0)
puts("\tUnexpected EOF, no ##end directive");
if (AutoOpt != 2)
GenerateLVOList(fo);
if (AutoOpt)
GenerateAutoOpen(fo, base);
}
/*
* funcname(var,var,var)(reg,reg,reg) (or reg/reg)
*/
static short FRegs[128];
void
GenerateFunction(fo, buf, base, bias)
FILE *fo;
char *buf;
char *base;
int bias;
{
char tmpFile[L_tmpnam];
char objFile[L_tmpnam+4];
char *funcName;
FILE *ft;
short argCnt;
short noArgs = 0;
funcName = buf;
while (*funcName && *funcName != '\t' && *funcName != ' ' && *funcName != '(')
++funcName;
if (*funcName == ' ' || *funcName == '\t') {
while (*funcName && *funcName != '(')
*funcName++ = 0;
}
if (*funcName == '(') {
*funcName++ = 0;
if (*funcName == ')')
noArgs = 1;
}
while (*funcName && *funcName != ')') /* skip text args */
++funcName;
while (*funcName && *funcName != '(')
++funcName;
if (noArgs == 0 && *funcName == 0) {
printf("\tError in line: %s\n", buf);
return;
}
/*
* get register description
*/
if (*funcName)
++funcName;
for (argCnt = 0; *funcName && *funcName != '\n' && *funcName != ')'; ++argCnt) {
switch(*funcName) {
case 'd':
case 'D':
FRegs[argCnt] = *++funcName - '0';
++funcName;
break;
case 'a':
case 'A':
FRegs[argCnt] = *++funcName - '0' + 8;
++funcName;
break;
default:
printf("\tError in register spec: %s\n", funcName);
return;
}
if (*funcName == ',' || *funcName == '/')
++funcName;
}
if (noArgs == 0 && *funcName != ')') {
printf("\tError in register spec: %s\n", funcName);
return;
}
/*
* generate
*/
funcName = strdup(buf);
{
RSNode *rs;
if (Verbose)
printf(" %-15s %d %d ", funcName, -bias, argCnt);
if (RegOpt) {
for (rs = (RSNode *)RSList.lh_Head; rs->rn_Node.ln_Succ; rs = (RSNode *)rs->rn_Node.ln_Succ) {
if (strcmp(rs->rn_Node.ln_Name + 1, funcName) == 0) {
rs->rn_Flag = 1;
break;
}
}
if (rs->rn_Node.ln_Succ == NULL) { /* (list tail) */
if (Verbose)
puts("NO MATCH FOUND");
return;
}
if (rs->rn_Args >= 0 && rs->rn_Args != argCnt) {
printf("Error, argCnt mismatch %s (%d/%d)\n", rs->rn_Node.ln_Name, rs->rn_Args, argCnt);
return;
}
}
if (Verbose)
fflush(stdout);
tmpnam(tmpFile);
sprintf(objFile, "%s.o", tmpFile);
if (RegOpt)
sprintf(FuncName, "%s", rs->rn_Node.ln_Name);
else
sprintf(FuncName, "%s%s", FuncPrefix, funcName);
if (ft = fopen(tmpFile, "w")) {
if (ProfOpt) {
fprintf(ft, "\txref\t__ProfInit\n");
fprintf(ft, "\txref\t__ProfExec\n");
fprintf(ft, "\n\tsection autoinit1,code\n");
fprintf(ft, "\tlea\tlp0%s,A0\n", DataModel);
fprintf(ft, "\tjsr\t__ProfInit\n", CodeModel);
fprintf(ft, "\n\tsection libdata,data\n");
fprintf(ft, "\tds.l\t0\n");
fprintf(ft, "lp0\n");
fprintf(ft, "\tdc.l\t0\n");
fprintf(ft, "\tdc.l\t0\n");
fprintf(ft, "\tdc.l\t0\n");
fprintf(ft, "\tdc.w\t%ld\n", (40 + strlen(FuncName) + (1 + 3)) & ~3);
fprintf(ft, "\tdc.w\t0\n");
fprintf(ft, "\tdc.l\t0\n");
fprintf(ft, "\tdc.l\t0\n");
fprintf(ft, "\tdc.l\t0\n");
fprintf(ft, "\tdc.l\t0\n");
fprintf(ft, "\tdc.l\tlp1\n");
fprintf(ft, "\tdc.l\tlp2\n");
fprintf(ft, "\tdc.b\t\'%s\',0\n", FuncName);
fprintf(ft, "\tds.l\t0\n");
}
fprintf(ft, "\n\tsection ,code\n\n");
fprintf(ft, "\txref\t%s\n\n", base);
fprintf(ft, "\txdef\t%s\n", FuncName);
fprintf(ft, "%s:\n", FuncName);
AddLVOList(funcName, -bias);
if (ProfOpt) {
fprintf(ft, "\tjsr\t__ProfExec%s\n", CodeModel);
fprintf(ft, "lp1\n");
}
if (RegOpt == 0 || rs->rn_Args == -1) { /* STACK CALL */
StackCall(ft, base, bias, FRegs, argCnt);
} else { /* REG CALL */
RegsCall(ft, base, bias, rs, FRegs);
}
fputs("\tEND\n", ft);
fclose(ft);
/*
* assemble the temp file
*/
if (Verbose)
puts("");
if (AssembleFile(tmpFile, objFile))
JoinOutput(fo, objFile);
remove(objFile);
remove(tmpFile);
} else {
printf("\tError, Unable to create file: %s\n", tmpFile);
}
}
}
void
ScanRSTmp(fi)
FILE *fi;
{
RSNode *rs;
char *ptr;
char *symPtr;
while (fgets(Buf, sizeof(Buf), fi)) {
if (strnicmp(Buf, "##regspec", 9) != 0)
continue;
for (ptr = Buf + 9; *ptr == ' ' || *ptr == '\t'; ++ptr);
symPtr = ptr;
while (*ptr && *ptr != '(')
++ptr;
if (*ptr != '(') {
printf("Error scanning RS file: %s\n", Buf);
continue;
}
*ptr++ = 0;
rs = malloc(sizeof(RSNode) + strlen(symPtr) + 1);
rs->rn_Node.ln_Name = (char *)(rs + 1);
rs->rn_Flag = 0;
strcpy(rs->rn_Node.ln_Name, symPtr);
if (*ptr == '*') {
rs->rn_Args = -1;
while (*ptr && *ptr != ')')
++ptr;
} else {
rs->rn_Args = 0;
while (*ptr && *ptr != ')') {
switch(*ptr) {
case 'd':
case 'D':
rs->rn_Regs[rs->rn_Args++] = ptr[1] - '0';
ptr += 2;
break;
case 'a':
case 'A':
rs->rn_Regs[rs->rn_Args++] = ptr[1] - '0' + 8;
ptr += 2;
break;
default:
printf("Error, Illegal RS file register spec: %s\n", ptr);
ptr = "";
break;
}
if (*ptr == ',')
++ptr;
}
}
if (*ptr != ')') {
printf("Error scanning RS file: %s\n", symPtr + strlen(symPtr) + 1);
continue;
}
if (Verbose > 1)
printf("RS-SCAN: %s (%d)\n", rs->rn_Node.ln_Name, rs->rn_Args);
AddTail((struct List *)&RSList, &rs->rn_Node);
}
}
int
AssembleFile(inFile, outFile)
char *inFile;
char *outFile;
{
remove(outFile);
if (Verbose > 2) {
FILE *fi;
if (fi = fopen(inFile, "r")) {
while (fgets(Buf, sizeof(Buf), fi))
fputs(Buf, stdout);
fclose(fi);
}
}
sprintf(Buf, "%sdas %s -o %s -nu",
Prefix,
inFile,
outFile
);
#ifdef unix
system(Buf);
#else
Execute(Buf, NULL, NULL);
#endif
return(1);
}
void
JoinOutput(fo, file)
FILE *fo;
char *file;
{
FILE *fi;
short c;
if (fi = fopen(file, "r")) {
while ((c = getc(fi)) != EOF)
putc(c, fo);
fclose(fi);
} else {
printf("Error, Can't read %s\n", file);
}
}
/*
* Generate assembly for a stack based call
*/
void
StackCall(FILE *ft, char *base, long bias, short *regs, short args)
{
uword mask = (RegsToMask(regs, args) | RF_BP) & ~RF_SCRATCH;
char *ptr;
short i;
short j;
short n;
/*
* step 1, what regs need to be saved?
*/
n = PushMask(ft, mask);
/*
* step 2, load regs from stack
*/
for (i = j = 0; i < args; i = j) {
uword lmask = 1 << regs[i];
short ln;
int offset = n * 4 + i * 4 + 4;
for (j = i + 1; j < args; ++j) {
if (regs[j] < regs[j-1])
break;
lmask |= 1 << regs[j];
}
ptr = RegMaskToStr(lmask, &ln);
if (ln > 1)
fprintf(ft, "\tmovem.l\t%d(sp),%s\n", offset, ptr);
else if (ln > 0)
fprintf(ft, "\tmove.l\t%d(sp),%s\n", offset, ptr);
}
/*
* step 3, load library base register
*/
fprintf(ft, "\tmove.l\t%s%s,A%d\n", base, DataModel, RB_BP - 8);
/*
* step 4, make call & return
*/
if (n) {
fprintf(ft, "\tjsr\t-%d(A%d)\n", bias, RB_BP - 8);
PopMask(ft, mask);
if (ProfOpt) {
fprintf(ft, "\tjsr\t__ProfExec%s\n", CodeModel);
fprintf(ft, "lp2\n");
}
fprintf(ft, "\tRTS\n");
} else {
if (ProfOpt) {
fprintf(ft, "\tjsr\t-%d(A%d)\n", bias, RB_BP - 8);
fprintf(ft, "\tjsr\t__ProfExec%s\n", CodeModel);
fprintf(ft, "lp2\n");
fprintf(ft, "\tRTS\n");
} else {
fprintf(ft, "\tjmp\t-%d(A%d)\n", bias, RB_BP - 8);
}
}
}
/*
* Generate assembly for a register based call
*/
void
RegsCall(ft, base, bias, rs, regs)
FILE *ft;
char *base;
long bias;
RSNode *rs;
short *regs;
{
uword mask = (RegsToMask(regs, rs->rn_Args) | RF_BP) & ~RF_SCRATCH;
short i;
short j;
short n;
/*
* step 1, what regs need to be saved?
*/
n = PushMask(ft, mask);
/*
* step 2, load regs from other regs. If destination is 'in use',
* then use EXG instead (and track where the reg went to)
*
* src: rs->rn_Regs[i]
* dest: regs[i]
*/
for (i = 0; i < rs->rn_Args; ++i) {
for (j = 0; j < rs->rn_Args; ++j) { /* is dest in use? */
if (i != j && regs[i] == rs->rn_Regs[j])
break;
}
if (j == rs->rn_Args) { /* not in use */
if (regs[i] != rs->rn_Regs[i]) { /* not in right plac */
fprintf(ft, "\tmove.l\t%s,%s\n", RegToStr(rs->rn_Regs[i]), RegToStr(regs[i]));
rs->rn_Regs[i] = -1;
}
} else {
fprintf(ft, "\texg.l\t%s,%s\n", RegToStr(rs->rn_Regs[i]), RegToStr(regs[i]));
rs->rn_Regs[j] = rs->rn_Regs[i];
rs->rn_Regs[i] = -1;
}
}
/*
* step 3, load library base register
*/
fprintf(ft, "\tmove.l\t%s%s,A%d\n", base, DataModel, RB_BP - 8);
/*
* step 4, make call and return
*/
if (n) {
fprintf(ft, "\tjsr\t-%d(A%d)\n", bias, RB_BP - 8);
PopMask(ft, mask);
if (ProfOpt) {
fprintf(ft, "\tjsr\t__ProfExec%s\n", CodeModel);
fprintf(ft, "lp2\n");
}
fprintf(ft, "\tRTS\n");
} else {
if (ProfOpt) {
fprintf(ft, "\tjsr\t-%d(A%d)\n", bias, RB_BP - 8);
fprintf(ft, "\tjsr\t__ProfExec%s\n", CodeModel);
fprintf(ft, "lp2\n");
fprintf(ft, "\tRTS\n");
} else {
fprintf(ft, "\tjmp\t-%d(A%d)\n", bias, RB_BP - 8);
}
}
}
char *
RegMaskToStr(uword mask, short *nr)
{
static char buf[64];
char *ptr = buf;
short i;
short l = -1;
*nr = 0;
for (i = 0; i < 8; ++i) {
if (mask & (1 << i)) {
++*nr;
if (l >= 0)
*ptr++ = '/';
ptr += sprintf(ptr, "D%d", i);
l = i;
}
}
for (i = 8; i < 16; ++i) {
if (mask & (1 << i)) {
++*nr;
if (l >= 0)
*ptr++ = '/';
ptr += sprintf(ptr, "A%d", i - 8);
l = i;
}
}
*ptr = 0;
return(buf);
}
uword
RegsToMask(short *regs, short args)
{
uword mask = 0;
while (args > 0) {
mask |= 1 << *regs++;
--args;
}
return(mask);
}
char *
RegToStr(short rno)
{
static char Buf[2][16];
static short BNo;
char *ptr = Buf[BNo];
BNo = 1 - BNo;
if (rno < 8)
sprintf(ptr, "D%d", rno);
else
sprintf(ptr, "A%d", rno - 8);
return(ptr);
}
short
PushMask(FILE *fo, uword mask)
{
short n;
char *ptr;
ptr = RegMaskToStr(mask, &n);
if (n > 1)
fprintf(fo, "\tmovem.l\t%s,-(sp)\n", ptr);
else if (n > 0)
fprintf(fo, "\tmove.l\t%s,-(sp)\n", ptr);
return(n);
}
short
PopMask(FILE *fo, uword mask)
{
short n;
char *ptr;
ptr = RegMaskToStr(mask, &n);
if (n > 1)
fprintf(fo, "\tmovem.l\t(sp)+,%s\n", ptr);
else if (n > 0)
fprintf(fo, "\tmove.l\t(sp)+,%s\n", ptr);
return(n);
}
void
AddLVOList(funcName, bias)
char *funcName;
int bias;
{
LVONode *node;
if (node = malloc(sizeof(LVONode) + strlen(funcName) + 1)) {
AddTail(&LVOList, &node->lv_Node);
node->lv_Node.ln_Name = (char *)(node + 1);
strcpy(node->lv_Node.ln_Name, funcName);
node->lv_Offset = bias;
}
}
void
GenerateLVOList(fo)
FILE *fo;
{
char tmpFile[L_tmpnam];
char objFile[L_tmpnam + 4];
LVONode *node;
FILE *ft;
tmpnam(tmpFile);
sprintf(objFile, "%s.o", tmpFile);
if (node = RemHead(&LVOList)) {
if (ft = fopen(tmpFile, "w")) {
fprintf(ft, "\n\tsection ,code\n\n");
while (node) {
if (Verbose)
printf("_LVO%-20s = %d\n", node->lv_Node.ln_Name, node->lv_Offset);
fprintf(ft, "_LVO%s\tEQU\t%d\n", node->lv_Node.ln_Name, node->lv_Offset);
fprintf(ft, "\txdef\t_LVO%s\n", node->lv_Node.ln_Name);
free(node);
node = RemHead(&LVOList);
}
fputs("\tEND\n", ft);
fclose(ft);
if (AssembleFile(tmpFile, objFile))
JoinOutput(fo, objFile);
remove(objFile);
remove(tmpFile);
}
}
}
/*
* generate auto-open tag code for this library
*/
void
GenerateAutoOpen(fo, base)
FILE *fo;
char *base;
{
char tmpFile[L_tmpnam];
char objFile[L_tmpnam + 4];
FILE *ft;
tmpnam(tmpFile);
sprintf(objFile, "%s.o", tmpFile);
if (ft = fopen(tmpFile, "w")) {
fprintf(ft, "\n\txdef\t%s\n", base);
fprintf(ft, "\n\txref\t__AutoFail0\n\n");
fprintf(ft, "_LVOOpenLibrary\tequ\t-552\n");
fprintf(ft, "_LVOCloseLibrary\tequ\t-414\n\n");
fprintf(ft, "\n\tsection autoinit0,code\n\n");
fprintf(ft, "\tmoveq.l\t#0,D0\n");
fprintf(ft, "\tlea\tlibname(pc),A1\n");
fprintf(ft, "\tjsr\t_LVOOpenLibrary(A6)\n");
fprintf(ft, "\tmove.l\tD0,%s%s\n", base, DataModel);
fprintf(ft, "\tbeq\t__AutoFail0\n");
fprintf(ft, "\tbra\topennext\n");
fprintf(ft, "libname\tdc.b\t'%s',0\n", SharedLibName);
fprintf(ft, "\tds.w\t0\n");
fprintf(ft, "opennext\n\n");
fprintf(ft, "\tsection autoexit0,code\n\n");
fprintf(ft, "\tmove.l\t%s%s,D0\n", base, DataModel);
fprintf(ft, "\tbeq\tclosenext\n");
fprintf(ft, "\tmove.l\tD0,A1\n");
fprintf(ft, "\tjsr\t_LVOCloseLibrary(A6)\n");
fprintf(ft, "closenext\n\n");
fprintf(ft, "\tsection libdata,data\n\n");
fprintf(ft, "%s\tdc.l\t0\n", base);
fputs("\tEND\n", ft);
fclose(ft);
if (AssembleFile(tmpFile, objFile))
JoinOutput(fo, objFile);
remove(objFile);
remove(tmpFile);
}
}
#ifdef LATTICE
char *
tmpnam(buf)
char *buf;
{
static char Buf[L_tmpnam];
static short Seq;
if (buf == NULL)
buf = Buf;
sprintf(buf, "T:%06lx%d", (long)FindTask(NULL) >> 4, Seq++);
return(buf);
}
#endif
void
DicePrefix(char *buf, char *av0, char *app)
{
char *ptr;
short n = 0;
for (ptr=av0+strlen(av0); ptr >= av0 && *ptr != '/' && *ptr != ':'; --ptr)
;
++ptr;
if (av0 = strchr(ptr, '_')) {
n = av0 - ptr + 1;
strncpy(buf, ptr, n);
}
strcpy(buf + n, app);
}